<template>
  <div>
    <PageTitleSearch
      :title="title"
      :hotelList="hotelList"
      :currentHotel="currentHotel"
      v-model:lastMonth="lastMonth"
      v-model:currentPre="currentPre"
      :currentAcc="currentAcc"
      :is-show-pre="true"
      @hotel-change="handleSelectChange"
      @date-change="handleDateSelect"
      @acc-change="handleAccSelect"
      @pre-change="handlePreSelect"
    />
    <div class="main-content">
      <FlexCard :loading="loading" :dataList="tableList">
        <TableCard :dataList="tableList" :columns="dataColumns" :scroll="tableHigh" :loading="loading" />
      </FlexCard>
    </div>
  </div>
</template>
<script>
  import dayjs from 'dayjs';

  import * as MathUtil from '/@/utils/MathUtil';
  import { defHttp } from '/@/utils/http/axios';
  import * as Constant from '/@/utils/Constant';
  import FlexCard from '@/views/applications/ui/FlexCard.vue';
  import TableCard from '@/views/applications/ui/ForecaseTable.vue';
  import PageTitleSearch from '@/views/applications/ui/PageTitleSearch.vue';
  const REPORT_NAME = '酒店月度预测（项目）';
  const COL_KEYS = ['actual', 'budget', 'lActual'];

  export default {
    name: REPORT_NAME,

    components: {
      FlexCard,
      TableCard,
      PageTitleSearch,
    },

    data() {
      return {
        title: '两个月预测',
        reportCode: '',
        reportName: '',
        loading: false,
        competLoading: false,
        tableHigh: { x: '100%', y: 480 },
        lastMonth: dayjs().subtract(1, 'month').format('YYYYMM'),
        hotelList: [],
        subjectList: [],
        preList: [
          { label: 'M+1预测', value: 1 },
          { label: 'M+2预测', value: 2 },
        ],
        currentHotel: {},
        currentPre: 1,
        roomData: [],
        priceData: [],
        perData: [],
        incomeData: [],
        rentRateData: [],
        gopRateData: [],
        competData: [],
        tableList: [],
        dataColumns: [
          {
            title: '项目',
            dataIndex: 'subjectName',
            key: 'subjectName',
            width: 200,
            align: 'left',
            ellipsis: true,
            fixed: 'left',
          },
          {
            dataIndex: 'actual',
            align: 'right',
            width: 100,
            children: [
              {
                title: '预测',
                dataIndex: 'actual',
                key: 'actual',
                width: 100,
                align: 'right',
                customRender: (val) => this.colRender(val.text, val.record),
              },
            ],
          },
          {
            dataIndex: 'budget',
            align: 'right',
            width: 100,
            children: [
              {
                title: '预算',
                dataIndex: 'budget',
                key: 'budget',
                width: 100,
                align: 'right',
                customRender: (val) => this.colRender(val.text, val.record),
              },
            ],
          },
          {
            dataIndex: 'lActual',
            align: 'right',
            width: 100,
            children: [
              {
                title: '去年',
                dataIndex: 'lActual',
                key: 'lActual',
                width: 100,
                align: 'right',
                customRender: (val) => this.colRender(val.text, val.record),
              },
            ],
          },
          {
            dataIndex: 'budgetDiff',
            title: '对比预算',
            align: 'right',
            className: 'table-header-color',
            width: 100,
            children: [
              {
                title: '差额',
                dataIndex: 'budgetDiff',
                key: 'budgetDiff',
                width: 100,
                align: 'right',
                className: 'table-header-color',
                customRender: (val) => this.colRender(val.text, val.record),
              },
            ],
          },
          {
            dataIndex: 'budgetDiffRate',
            align: 'right',
            className: 'table-header-color',
            width: 100,
            children: [
              {
                title: '差异率',
                dataIndex: 'budgetDiffRate',
                key: 'budgetDiffRate',
                width: 100,
                align: 'right',
                className: 'table-header-color',
                customRender: (val) => MathUtil.percent2DFormatter(val, 1),
              },
            ],
          },
          {
            dataIndex: 'lDiff',
            title: '对比去年',
            align: 'right',
            width: 100,
            children: [
              {
                title: '差额',
                dataIndex: 'lDiff',
                key: 'lDiff',
                width: 100,
                align: 'right',
                customRender: (val) => this.colRender(val.text, val.record),
              },
            ],
          },
          {
            dataIndex: 'lDiffRate',
            align: 'right',
            width: 100,
            children: [
              {
                title: '差异率',
                dataIndex: 'lDiffRate',
                key: 'lDiffRate',
                width: 100,
                align: 'right',
                customRender: (val) => MathUtil.percent2DFormatter(val, 1),
              },
            ],
          },
        ],
      };
    },

    created() {
      Promise.all([
        defHttp.get({ url: '/data/hotel/list' }, { isTransformResponse: false }),
        defHttp.post({
          url: '/data/query',
          data: {
            labelCode: 'getHotelForecastOptSubject',
            sqlParams: [],
            pageIndex: 1,
            pageSize: 100,
          },
        }),
      ]).then((res) => {
        const [hotelRes, subjectRes] = res;
        if (hotelRes.success && hotelRes.result.length > 0 && subjectRes.datas.data) {
          const dataList = hotelRes.result;
          this.hotelList = dataList.map((s) => {
            return { label: s.name, value: s.code };
          });
          const currentHotelCode = this.$route.query.hotelCode || localStorage.getItem(Constant.STORAGE_HOTEL_NAME);
          if (currentHotelCode && dataList.filter((d) => d.code === currentHotelCode).length > 0) {
            this.currentHotel = dataList.filter((d) => d.code === currentHotelCode)[0];
          } else {
            this.currentHotel = {
              code: dataList[0].code,
              name: dataList[0].name,
            };
          }
          this.hotelSel = this.currentHotel;
          this.subjectList = subjectRes.datas.data;
          this.dataColumns[0].title = this.currentHotel.name;
          const preName = this.preList.filter((p) => p.value === this.currentPre)[0].label;
          this.dataColumns[2].title = preName;
          this.fetchData();
        }
      });
    },

    methods: {
      handleAccSelect(value) {
        this.currentAcc = value;
      },
      fetchData() {
        this.loading = true;
        defHttp
          .post({
            url: 'data/query',
            data: {
              labelCode: 'getHotelMonthForecast',
              sqlParams: [
                {
                  key: 'code',
                  value: this.currentHotel.code,
                },
                {
                  key: 'month',
                  value: this.lastMonth,
                },
                {
                  key: 'pre',
                  value: this.currentPre,
                },
              ],
              pageIndex: 1,
              pageSize: 100,
            },
          })
          .then((res) => {
            if (res.datas.success && res.datas.data.length > 0) {
              const datas = res.datas.data;
              let dataList = this.subjectList.map((s) => {
                let d = {
                  subjectCode: s.code,
                  subjectName: s.name,
                  showFormatter: s.showFormatter,
                };
                if (s.calMode === 'DEFAULT') {
                  COL_KEYS.forEach((c) => {
                    const item = datas.filter((l) => l.subjectCode === s.code);
                    d[c] = item.length > 0 ? item[0][c] : 0;
                  });
                  d = this.wrapData(d);
                }
                return d;
              });

              this.subjectList.forEach((s) => {
                if (s.calMode === 'AUTO') {
                  dataList = dataList.map((d) => {
                    if (d.subjectCode === s.code) {
                      COL_KEYS.forEach((c) => {
                        const replacedFormula = s.formula.replace(/#\{(\w+)\}/g, (_, code) => {
                          const ds = dataList.filter((l) => l.subjectCode === code);
                          return ds.length > 0 ? ds[0][c] : 0;
                        });
                        d[c] = eval(replacedFormula) || 0;
                      });
                      d = this.wrapData(d);
                    }
                    return d;
                  });
                }
              });
              this.tableList = dataList;
            } else {
              this.tableList = [];
            }
            localStorage.setItem(Constant.STORAGE_HOTEL_NAME, this.currentHotel.code);
            this.loading = false;
          });
      },
      wrapData(data) {
        return {
          ...data,
          budgetDiff: data.actual - data.budget,
          budgetDiffRate: MathUtil.diff(data.actual, data.budget),
          lDiff: data.actual - data.lActual,
          lDiffRate: MathUtil.diff(data.actual, data.lActual),
        };
      },
      colRender(val, record) {
        if (record.showFormatter) {
          const [methodName, ...params] = record.showFormatter.split('|');
          if (typeof MathUtil[methodName] === 'function') {
            return MathUtil[methodName](val, ...params);
          }
        }
        return val;
      },
      filterOption(input, option) {
        return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0;
      },
      handleSelectChange(value) {
        this.currentHotel = {
          code: value,
          name: this.hotelList.filter((h) => h.value === value)[0].label,
        };
        this.dataColumns[0].title = this.currentHotel.name;
        this.fetchData();
      },
      handlePreSelect(value) {
        this.currentPre = value;
        this.dataColumns[2].title = this.preList.filter((p) => p.value === this.currentPre)[0].label;
        this.fetchData();
      },
      isMonthDisabled(current) {
        const lastMonth = dayjs().subtract(1, 'month');
        return current.isAfter(lastMonth);
      },
      handleDateSelect() {
        this.fetchData();
      },
    },
  };
</script>

<style lang="less" scoped>
  .main-content {
    padding: 12px 0;

    &-title {
      &-custom {
        color: #00b578;
      }
    }
  }

  .card-double {
    display: flex;
    margin: 12px 0 12px 0;
    justify-content: space-between;

    &-item {
      flex-basis: 48%;
    }
  }

  .interval-area {
    margin-bottom: 12px;
  }

  .select-title-space {
    width: 200px;
    margin-right: 20px;
  }

  ::v-deep .select-title .van-cell {
    color: hsl(217, 16%, 60%);
    font-size: 0.875rem;
    line-height: 1.25rem;
    padding: unset;
    -webkit-box-pack: end;
    -ms-flex-pack: end;
    justify-content: flex-end;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    position: relative;
    background-color: #112c4d;
  }

  ::v-deep .a-mobile-select .van-cell__value {
    color: #ffffff;
    font-size: 18px;
    font-weight: 500;
    padding-right: 0.5rem;
    text-align: center;
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    text-overflow: ellipsis;
  }

  ::v-deep .a-mobile-select .van-cell .select-suffix-icon {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    width: 1.25rem;
    height: 1.25rem;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
    font-size: 1rem;
    color: #8894a8;
  }

  .popup-right {
    width: auto;

    &-content {
      height: 800px;
      width: 318px;

      &-oprate {
        display: flex;
        padding: 16px;
        justify-content: center;

        &-item {
          width: 100%;
          margin-right: 10px;
        }

        &-item:last-child {
          margin-right: 0;
        }
      }
    }
  }

  @media @desktop {
    .row-content {
      display: flex;
    }

    .main-frame-desktop-header {
      padding: 1rem;
      background: #fff;
      overflow: hidden;
    }

    .a-layout-form-vertical,
    .a-layout-form-horizontal {
      width: 30rem;
      margin: 0 auto 5rem auto;
    }

    .a-layout-form-inline__warn {
      color: #ffb829;
      text-align: center;
    }

    .a-layout-form-inline .a-basic-layout-form-button button {
      min-width: 5rem;
      margin-right: 0.5rem;
    }

    .echarts {
      width: 100%;
      height: 236px;
    }

    .title-name {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 36px;
      background: #ffffff;
      -webkit-box-shadow: 0px 5px 5px 0px rgba(25, 15, 15, 0.07);
      box-shadow: 0px 5px 5px 0px rgba(25, 15, 15, 0.07);
      border-radius: 0.25rem;
      margin: 10px;
      font-size: 16px;
      font-weight: 600;
    }

    .flex-height {
      white-space: pre-line;
      height: 268px;
    }
    .card-flex-all {
      flex: 1 1 calc(100% - 10px);
    }
  }
</style>
